using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LS.GameKit.Behaviour;
using UnityEngine.Events;

namespace LS.GameKit
{
    public class SimpleTranslator : TransformerBehaviour
    {
        public bool usePhysicsBehaviour = true;
        public Space translateSpace = Space.Self;
        public Transform activedTransform;
        public PhysicsBehaviour activedPhysicsBehaviour;
        public Vector3 start = Vector3.zero;
        public Vector3 end = Vector3.right;

        public override void PerformTransform(float position)
        {
            var curvePosition = accelCurve.Evaluate(position);
            var pos = Vector3.Lerp(start, end, curvePosition);

            if (translateSpace == Space.Self)
                pos = LocalToWorldPosition(pos);

            Vector3 delta = pos - GetPosition();
            Translate(delta);
            this.OnDeltaPosition?.Invoke(delta);
            this.OnPositionChanged?.Invoke(pos);
        }

        public void Translate(Vector3 delta)
        {
            Translate(delta, Space.World);
        }

        public void Translate(Vector3 delta, Space space)
        {
            if (usePhysicsBehaviour)
            {
                if (space == Space.Self)
                    activedPhysicsBehaviour.TranslateLocal(delta);
                else
                    activedPhysicsBehaviour.Translate(delta);
            }
            else
            {
                if (space == Space.Self)
                    activedTransform.Translate(delta, Space.Self);
                else
                    activedTransform.Translate(delta, Space.World);
            }
        }

        public void SetPosition(Vector3 position)
        {
            SetPosition(position, Space.World);
        }

        public void SetPosition(Vector3 position, Space space)
        {
            if (usePhysicsBehaviour && activedPhysicsBehaviour != null)
            {
                if (space == Space.Self)
                    activedPhysicsBehaviour.LocalPosition = position;
                else
                    activedPhysicsBehaviour.Position = position;
            }
            else
            {
                if (space == Space.Self)
                    activedTransform.localPosition = position;
                else
                    activedTransform.position = position;
            }
        }

        public Vector3 GetPosition()
        {
            return GetPosition(Space.World);
        }

        public Vector3 GetPosition(Space space)
        {
            if (usePhysicsBehaviour && activedPhysicsBehaviour != null)
                return space == Space.Self ? activedPhysicsBehaviour.LocalPosition : activedPhysicsBehaviour.Position;
            else
                return space == Space.Self ? activedTransform.localPosition : activedTransform.position;
        }

        private Vector3 LocalToWorldPosition(Vector3 position)
        {
            if (usePhysicsBehaviour && activedPhysicsBehaviour != null)
            {
                return activedPhysicsBehaviour.CachedTransform.parent.TransformPoint(position);
            }
            else
            {
                return activedTransform.parent.TransformPoint(position);
            }
        }

        protected virtual void Reset()
        {
            activedPhysicsBehaviour = GetComponentInChildren<PhysicsBehaviour>();
            if (activedPhysicsBehaviour != null)
            {
                activedTransform = activedPhysicsBehaviour.transform;
                return;
            }

            if (transform.childCount > 0)
            {
                activedTransform = transform.GetChild(0);
            }
            else activedTransform = transform;
        }

#if UNITY_EDITOR
        private void OnDrawGizmosSelected()
        {
            Vector3 tstart = start;
            Vector3 tend = end;
            if (translateSpace == Space.Self)
            {
                tstart = transform.TransformPoint(tstart);
                tend = transform.TransformPoint(tend);
            }
            Color col = Color.blue;
            col.a = 0.75f;
            Gizmos.color = col;
            Gizmos.DrawLine(tstart, tend);
            Gizmos.DrawCube(tstart, Vector3.one * 0.2f);
            Gizmos.DrawCube(tend, Vector3.one * 0.2f);
            var curvePosition = accelCurve.Evaluate(previewPosition);
            var pos = Vector3.Lerp(start, end, curvePosition);
            if (translateSpace == Space.Self)
                pos = transform.TransformPoint(pos);
            col = Color.cyan;
            col.a = 0.75f;
            Gizmos.color = col;
            Gizmos.DrawCube(pos, Vector3.one);
        }
#endif

    }
}
